'''
Coron Lattice Drawer
Author: Victor Codocedo H.
Universintentd Tecnica Federico Santa Maria

Usage:
python coron_drawer.py lats/baclat.lat

baclat.lat is the output of LECO from Coron.
Add names, extension and stability options when executing LECO.
LECO is provided on Coron
'''
from vtk import *
import sys
from lattice_functions import *

def printParents(e):
	if extent[e]["level"] <= 0:
		return []
	result = []
	for p in extent[e]["parents"]:
		#arrow = str(extent[e]["level"])
		#for i in range(extent[e]["level"]-1):
		#	arrow += "-"
		#print arrow+">"+str(extent[p]["objects"][:5])
		result.append(p)
		parents = printParents(p)
		for i in parents:
			if i not in result:
				result.append(i)
	return result
	
def printChildren(e):
	if extent[e]["level"] >= maxlev:
		return []
	result = []
	for p in extent[e]["children"]:
		#arrow = str(extent[e]["level"])
		#for i in range(extent[e]["level"]-1):
		#	arrow += "-"
		#print arrow+">"+str(extent[p]["objects"][:5])
		result.append(p)
		children = printChildren(p)
		for i in children:
			if i not in result:
				result.append(i)
	return result


def selectionCallback(caller, event):
	print "Searching subgraph..."
	sel = caller.GetSelection()
	node0 = sel.GetNode(0)
		
	fil = vtkIdTypeArray()
	if node0.GetFieldType() == 3:
		sl = node0.GetSelectionList()
		if sl.GetNumberOfTuples() > 0:
			fil.InsertValue(0,sl.GetValue(0))
			parents = printChildren(vertex_inv[sl.GetValue(0)])
			j = 1
			for p in parents:
				#print p,str(vertex[p])
				fil.InsertValue(j, int(vertex[p]))
				j += 1
			
		else:
			print "No concept selected"
	node0.SetSelectionList(fil)
	#sel.RemoveNode(0)
	#sel.AddNode(node0)
	#caller.SetSelection(sel)
	view2.GetRenderer().ResetCamera()
	view2.GetRenderer().Render()
	sel.Update()
	print "Subgraph search ended"
 
def printFieldType(field_type):
       if field_type == 3:
               print "Vertices Selected:"
       elif field_type == 4:
               print "Edges Selected:"
       else:
               print "Unknown type:"


#####################################################
######## MAIN CODE ##################################
#####################################################
staboffset=0
doClean = True
lattice = ""
if len(sys.argv)<2:
	print "\n*** usage:",sys.argv[0]," [latfile]"
	exit()
else:
	lattice = sys.argv[1]

extent,levels,maxlev = readLattice(lattice)

if doClean:
	#CLEAN LATTICE
	forclean = []
	for e in levels[maxlev]:
		forclean = extent[e]["objects"]
		clean(e,forclean,[],extent)

# GRAPH AS DIRECTED
g=vtkMutableDirectedGraph()

# CREATE VERTICES
vertex,points,vertex_id_array,stab_vertex_array,sup_vertex_array,intent_array = create_lattice_vertices(g,extent,levels,maxlev,staboffset)
print vertex
# CREATING INVERTED VERTEX INDEX
vertex_inv = {}
for i in vertex:
	vertex_inv[vertex[i]] = i
	
# CREATE EDGES
create_lattice_edges(g,vertex,extent)

# ASSIGN GRAPH DATA TO THE GRAPH
g.GetVertexData().AddArray(stab_vertex_array)
g.GetVertexData().AddArray(sup_vertex_array)
g.GetVertexData().AddArray(vertex_id_array)
g.GetVertexData().AddArray(intent_array)
g.SetPoints(points)

strat = vtkPassThroughLayoutStrategy()
layout = vtk.vtkGraphLayout()
layout.SetInput(g)
layout.SetLayoutStrategy(strat)

# CREATE LAYOUT
view = vtkGraphLayoutView()

# SET THE LABELS FOR EACH NODE
view.SetVertexLabelArrayName("names")
view.SetVertexLabelVisibility(True)
view.SetVertexLabelFontSize(15)

view.SetVertexColorArrayName("support")
view.SetColorVertices(True)

# Graph-View Binding
view.AddRepresentationFromInputConnection(layout.GetOutputPort())
#view.AddRepresentationFromInput(g)
view.SetLayoutStrategyToPassThrough()

# Event Configuration
link = vtkSelectionLink()
view.GetRepresentation(0).SetSelectionLink(link)
link.AddObserver("SelectionChangedEvent", selectionCallback)

# Take selection and extract a graph
extract_graph = vtkExtractSelectedGraph()
extract_graph.AddInputConnection(layout.GetOutputPort())
extract_graph.SetSelectionConnection(link.GetOutputPort())

# Create a view for the extracted graph
#g1 = g
view2 = vtkGraphLayoutView()
view2.SetVertexLabelArrayName("names")
view2.SetVertexLabelVisibility(True)
view2.SetVertexLabelFontSize(15)
view2.SetVertexColorArrayName("support")
view2.SetColorVertices(True)
view2.AddRepresentationFromInputConnection(extract_graph.GetOutputPort())
view2.SetLayoutStrategyToPassThrough()
#view2.SetLayoutStrategyToCircular()


#view2.GetRepresentation(0).SetSelectionLink(link)


# VISUALIZATION CONFIGURATION
# Set up the theme
theme = vtkViewTheme.CreateMellowTheme()
theme.SetCellColor(.2,.2,.6)
view.ApplyViewTheme(theme)
view2.ApplyViewTheme(theme)
theme.FastDelete()

updater = vtkViewUpdater()
updater.AddView(view)
updater.AddView(view2)

render = vtkXOpenGLRenderWindow()
inter = vtkXRenderWindowInteractor()
render.SetInteractor(inter)
view.SetupRenderWindow(render)
view.GetRenderWindow().SetSize(600,600)
render.Render()

window2 = vtkRenderWindow()
window2.SetSize(600, 600)
view2.SetupRenderWindow(window2)
view2.GetRenderer().ResetCamera()
view2.GetRenderer().Render()


render.GetInteractor().Start()

# PRINTING SUMMARY
for i in levels:
	print "Cantintentd del nivel " + str(i) + ": " + str(len(levels[i]))
